package com.running.base.run.util;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class HttpClientUtils {

    private static final Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);

    private static DefaultHttpClient httpClient = null;

    private static final String defaultCharset = Constants.CHAR_SET;

    public static HttpClient getHttpClient() {
        if (httpClient == null) {
            synchronized (HttpClientUtils.class) {
                if (httpClient == null) {
                    init();
                }
            }
        }
        return httpClient;
    }

    private static void init() {
        HttpParams params = new BasicHttpParams();
        //设置连接超时时间
        Integer CONNECTION_TIMEOUT = 10 * 1000;
        Integer SO_TIMEOUT = 15 * 1000;
        Long CONN_MANAGER_TIMEOUT = 500L;

        params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIMEOUT);
        params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SO_TIMEOUT);
        params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, CONN_MANAGER_TIMEOUT);
        //在提交请求之前 测试连接是否可用
        params.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false);

        PoolingClientConnectionManager conMgr = new PoolingClientConnectionManager();
        conMgr.setMaxTotal(200);
        conMgr.setDefaultMaxPerRoute(conMgr.getMaxTotal());

        httpClient = new DefaultHttpClient(conMgr);
        //retry times
        httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(3, true));
        httpClient.setParams(params);
    }

    private static String getQueryUrl(String url, Map<String, String> param) {
        StringBuilder formatUrl = new StringBuilder();
        if (!CollectionUtils.isEmpty(param)) {
            for (Map.Entry<String, String> entry : param.entrySet()) {
                formatUrl.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }

        String res = formatUrl.toString();
        return url + "?" + res.substring(0, res.length() - 1);
    }

    public static void main(String[] args) {
        for (int i=0; i<10;i++) {
            String url = "https://juejin.cn/post/7162507932393799694";
            Map<String, String> param = new HashMap<>();
            param.put("word", "query");
            sendGet(url, param);
        }

    }

    public static String sendGet(String url, Map<String, String> param) {
        String formatUrl = null;
        try {
            formatUrl = getQueryUrl(url, param);
            HttpGet httpGet = new HttpGet(formatUrl);
            HttpResponse response = null;
            response = HttpClientUtils.getHttpClient().execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (HttpStatus.SC_OK != statusCode) {
                throw new RuntimeException("HttpClientUtils error status code :" + statusCode + ",aliUrl=" + formatUrl);
            }
            String message = EntityUtils.toString(response.getEntity(), defaultCharset);
            logger.info("Method : HttpClients | sendGet res===" + message + ",aliUrl===" + formatUrl);
            return message;
        } catch (IOException e) {
            logger.error("Method : HttpClientUtils | sendGet error ! aliUrl = " + formatUrl, e);
        }

        return null;

    }

    public static String sendPost(String url, String jsonBody) {
        try {
            HttpPost httpPost = new HttpPost(url);
            StringEntity stringEntity = new StringEntity(jsonBody, Constants.CHAR_SET);
            httpPost.setEntity(stringEntity);
            httpPost.setHeader("Content-Type", "application/json");
            HttpResponse resp = HttpClientUtils.getHttpClient().execute(httpPost);
            int statusCode = resp.getStatusLine().getStatusCode();
            if (HttpStatus.SC_OK != statusCode) {
                throw new RuntimeException("HttpClientUtils error status code :" + statusCode + ",aliUrl=" + url);
            }

            String message = EntityUtils.toString(resp.getEntity(), defaultCharset);
            logger.info("Method : HttpClients | sendPost res===" + message + ",aliUrl===" + url);
            return message;
        } catch (IOException e) {
            logger.error("Method : HttpClientUtils | sendPost error，aliUrl = " + url, e);
        }
        return null;
    }

}

